package com.fy.restfulapi.response;

import com.fy.restfulapi.constant.CommonErrorCode;

import java.util.Date;

/**
 * @author sunlei
 */
public class R<T> {
    private Boolean success;
    private Integer code;
    private String message;
    private Date timestamp;
    private T data;

    // getter
    public Boolean getSuccess() {
        return success;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public T getData() {
        return data;
    }

    // setter
    public R<T> setSuccess(Boolean success) {
        this.success = success;
        return this;
    }

    private R<T> setCode(Integer code) {
        this.code = code;
        return this;
    }

    private R<T> setMessage(String message) {
        this.message = message;
        return this;
    }

    private R<T> setData(T data) {
        this.data = data;
        return this;
    }

    // construct
    private R(Date timestamp) {
        this.timestamp = timestamp;
    }

    /********************************** public apis *****************************/

    // 类方法，快速构建统一的返回对象
    /**
     * 根绝指定的枚举对象构造响应对象
     * @param result
     * @return
     */
    public static <T> R<T> setResult(CommonErrorCode result) {
        return new R<T>(new Date())
                .setSuccess(result.getSuccess())
                .setCode(result.getCode())
                .setMessage(result.getMessage());
    }

    /**
     * 构造通用请求【成功】对象
     * @return 返回统一格式的返回对象
     */
    public static <T> R<T> success() {
        return R.setResult(CommonErrorCode.SUCCESS);
    }

    /**
     * 构造通用请求【失败】对象
     * @return 返回统一格式的返回对象
     */
    public static <T> R<T> failure() {
        return R.setResult(CommonErrorCode.FAIL);
    }

    // 实例对象方法，设置统一返回格式的某个值
    /**
     * 设置请求是否成功
     * @param success
     * @return
     */
    public R<T> success(Boolean success) {
        return this.setSuccess(success);
    }

    /**
     * 设置响应码
     * @param code
     * @return
     */
    public R<T> code(Integer code) {
        return this.setCode(code);
    }

    /**
     * 设置响应的消息
     * @param message
     * @return
     */
    public R<T> message(String message) {
        return this.setMessage(message);
    }

    /**
     * 设置要返回的泛型数据
     * @param data
     * @return
     */
    public R<T> data(T data) {
        return this.setData(data);
    }
}
